/***************************************************************
 * Name:      testwx4Main.cpp
 * Purpose:   Code for Application Frame
 * Author:     ()
 * Created:   2011-05-18
 * Copyright:  ()
 * License:
 **************************************************************/

#include <string>
#include <enet/enet.h>

#include "testwx4Main.h"
#include <wx/msgdlg.h>

//(*InternalHeaders(testwx4Dialog)
#include <wx/intl.h>
#include <wx/string.h>
//*)

//helper functions
enum wxbuildinfoformat {
    short_f, long_f };

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}

//(*IdInit(testwx4Dialog)
const long testwx4Dialog::ID_LISTBOX1 = wxNewId();
const long testwx4Dialog::ID_TEXTCTRL2 = wxNewId();
const long testwx4Dialog::ID_BUTTON1 = wxNewId();
//*)
const long testwx4Dialog::ID_TIMER = wxNewId();

BEGIN_EVENT_TABLE(testwx4Dialog,wxDialog)
    //(*EventTable(testwx4Dialog)
    //*)
    EVT_TIMER(ID_TIMER, testwx4Dialog::OnTimer)
END_EVENT_TABLE()

testwx4Dialog::testwx4Dialog(wxWindow* parent,wxWindowID id):
    mIndex(0)
{
    //(*Initialize(testwx4Dialog)
    Create(parent, wxID_ANY, _("Chat Box"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("wxID_ANY"));
    BoxSizer1 = new wxBoxSizer(wxVERTICAL);
    Output = new wxListBox(this, ID_LISTBOX1, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_LISTBOX1"));
    Output->SetMinSize(wxSize(0,400));
    Output->SetMaxSize(wxSize(0,400));
    BoxSizer1->Add(Output, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
    TxtInput = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER, wxDefaultValidator, _T("ID_TEXTCTRL2"));
    TxtInput->SetFocus();
    BoxSizer2->Add(TxtInput, 4, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BtnSend = new wxButton(this, ID_BUTTON1, _("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
    BtnSend->SetMinSize(wxSize(64,32));
    BoxSizer2->Add(BtnSend, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer1->Add(BoxSizer2, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
    SetSizer(BoxSizer1);
    BoxSizer1->Fit(this);
    BoxSizer1->SetSizeHints(this);
    Center();

    Connect(ID_TEXTCTRL2,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&testwx4Dialog::OnTxtInputTextEnter);
    Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&testwx4Dialog::OnQuit);
    //*)
    enet_initialize();

    writeBox(_("Please enter server IP.."));
    mState = CBAskIP;
    mTimer = new wxTimer(this,ID_TIMER);
    mTimer->Start(10);
}

testwx4Dialog::~testwx4Dialog()
{
    //(*Destroy(testwx4Dialog)
    //*)
    KMNetClient::disconnect();
    mTimer->Stop();
    delete mTimer;
    enet_deinitialize();
}

void testwx4Dialog::OnQuit(wxCommandEvent& event)
{
    Close();
}

void testwx4Dialog::writeBox(const wxString &str)
{
    wxArrayString tmp(1,str);
    Output->InsertItems(tmp,mIndex);
    mIndex++;
}

void testwx4Dialog::OnTxtInputTextEnter(wxCommandEvent& event)
{
    wxString line(TxtInput->GetValue());
    TxtInput->Clear();
    switch( mState )
    {
        case CBAskIP:
        {
            mIP = line;
            writeBox(_("Please enter server port.."));
            mState = CBAskPort;
            break;
        }
        case CBAskPort:
        {
            bool getPort = line.ToLong(&mPort);
            if( !getPort ||
                !KMNetClient::connectToServer(std::string(mIP.mb_str()),mPort) )
            {
                writeBox(_("Connect to server failed"));
                writeBox(_("Please enter server IP.."));
                mState = CBAskIP;
            }
            else
            {
                writeBox(_("Connect to server success"));
                writeBox(_("Please enter username.."));
                mState = CBAskUsername;
            }
            break;
        }
        case CBAskUsername:
        {
            mUserName = line;
            sendUserName();
            writeBox(_("Please wait.."));
            mState = CBWaiting;
            break;
        }
        case CBConnected:
        {
            sendChat(line);
            break;
        }
        default: break;
    }
}

void testwx4Dialog::OnTimer(wxTimerEvent& event)
{
    if(mState > CBAskPort )
    {
        KMNetClient::update();
    }
}

void testwx4Dialog::sendUserName()
{
    std::string usr(mUserName.mb_str());
    KMNetMsgOut msg;
    msg.writeId(CSLOGIN);
    msg.writeString(usr);
    KMNetClient::send(msg);
}

void testwx4Dialog::sendChat(const wxString &chat)
{
    wxString line = _("[");
    line = line.Append(mUserName);
    line = line.Append(_("] "));
    line = line.Append(chat);
    std::string usr(line.mb_str());
    KMNetMsgOut msg;
    msg.writeId(CSCHAT);
    msg.writeString(usr);
    KMNetClient::send(msg);
}

void testwx4Dialog::processMessageFromServer(KMNetMsgIn &msg)
{
    int id = 0;

    if( !msg.readId(id) ) return;

    switch(id)
    {
        case SCLOGIN:
        {
            int result = 0;
            msg.read2Bytes(result);

            std::string answer;
            msg.readString(answer);

            wxString line(answer.c_str(), wxConvUTF8);
            writeBox(line);

            if( result )
            {
                mState = CBConnected;
            }
            else
            {
                writeBox(_("Please enter username.."));
                mState = CBAskUsername;
            }
            break;
        }
        case SCCHAT:
        {
            std::string answer;
            msg.readString(answer);

            wxString line(answer.c_str(), wxConvUTF8);
            writeBox(line);

            break;
        }
        default: break;
    }
}


